package com.isprint.jslx.base.inteceptor;

import com.isprint.jslx.anno.JslxService;
import com.isprint.jslx.cdn_resource.CdnResource;
import com.jfinal.aop.Duang;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.kabao.ext.kit.CookieKit;

import javax.servlet.http.Cookie;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.UUID;

/**
 * 拦截器基类
 * @ClassName InterceptorBase
 * @Description 拦截器基类
 * @author Ryan
 */
public abstract class InterceptorBase implements Interceptor {
	

	private static Log log = Log.getLog(InterceptorBase.class);
	/**
	 * UUIDNAME COOKIE名称
	 */
	private String UUIDNAME;
	public String getUUIDNAME() {
		return UUIDNAME;
	}
	public void setUUIDNAME(String uUIDNAME) {
		UUIDNAME = uUIDNAME;
	}
	/**
	 * COOKIEEXPIRETIME 分钟
	 */
	private int COOKIEEXPIRETIME;
	public int getCOOKIEEXPIRETIME() {
		return COOKIEEXPIRETIME;
	}
	public void setCOOKIEEXPIRETIME(int cOOKIEEXPIRETIME) {
		COOKIEEXPIRETIME = cOOKIEEXPIRETIME;
	}
	/**
	 * DOMAIN 域
	 */
	private String DOMAIN;
	public String getDOMAIN() {
		return DOMAIN;
	}
	public void setDOMAIN(String dOMAIN) {
		DOMAIN = dOMAIN;
	}
	/**
	 * ATTRIBUTENAME 属性名称
	 */
	private String ATTRIBUTENAME;
	public String getATTRIBUTENAME() {
		return ATTRIBUTENAME;
	}
	public void setATTRIBUTENAME(String aTTRIBUTENAME) {
		ATTRIBUTENAME = aTTRIBUTENAME;
	}
	public InterceptorBase(){
		init();
	}
	/**
	 * 子类必须实现
	 */
	public abstract void init();

	private Method getSetMethod(Field declaredField, Class<? extends Controller> clazz) {
		String name = declaredField.getName();
		String s = (name.charAt(0) + "").toUpperCase() + name.substring(1);
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
            if (method.getName().equals("set"+s)) {
                method.setAccessible(true);
                return method;
            }
        }

		return null;
	}
	public void intercept(Invocation ai) {
		Controller controller = ai.getController();
		Class<? extends Controller> clazz = controller.getClass();
		Field[] declaredFields = clazz.getDeclaredFields();
		for (Field declaredField : declaredFields) {
			if (declaredField.isAnnotationPresent(JslxService.class)) {
				if (declaredField.getName().endsWith("Service")||declaredField.getName().endsWith("ServiceImpl")) {
					declaredField.setAccessible(true);
					Method setMethod = getSetMethod(declaredField, clazz);
					Class<?> filedClazz = declaredField.getType();
					try {
						setMethod.invoke(controller,Duang.duang(declaredField.getType()));
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					}
				}
			}

		}
		String aa = ai.getActionKey();
		String cookieValue = null;
		UUID uuid = UUID.randomUUID();
		//根据cookie的名字获得一个cookie
		Cookie cookieUUID = CookieKit.getCookie(controller.getRequest(), this.getUUIDNAME());
		if(cookieUUID == null){
			//如果是第一次登入的话,则添加一个名字为uuidname的cookie,这个cookie的值为一个randomuuid;
			CookieKit.addCookie(controller.getResponse(), this.getUUIDNAME(), uuid.toString(), this.getCOOKIEEXPIRETIME(), "/", this.getDOMAIN());
			cookieValue = uuid.toString();
		}else{
			cookieValue = cookieUUID.getValue();
		}
		//把cookie的值存入和一个常量存入到request域中
		controller.getRequest().setAttribute(this.getATTRIBUTENAME(), cookieValue);
		controller.getRequest().setAttribute("resource", CdnResource.CDNRESOURCE);
		try {
			ai.invoke();
		} catch (Exception e) {
			//报警描述编辑
			String redirctUrl = controller.getRequest().getHeader("referer");
	        if(StrKit.isBlank(redirctUrl)){
	          redirctUrl = controller.getRequest().getRequestURI();
	        }
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace();
			e.printStackTrace(pw);
			log.error("业务逻辑代码遇到异常时保存日志:"+e.getMessage());
			Enumeration<String> enus = controller.getAttrNames();
			while (enus.hasMoreElements()) {
				controller.removeAttr(enus.nextElement());
			}
			controller.setAttr("status", 1);
			controller.setAttr("result", "您的网络不给力呀");
			errorRenderWrapper(controller);
		} finally {
			
		}
	}




	/**
	 * 错误 Render 包装器
	 * @param controller
	 */
	public abstract void errorRenderWrapper(Controller controller);
}
